﻿using OfficeOpenXml.Drawing.Chart;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Wq.CaseService;
using Wq.CaseService.Entities;
using Wq.CaseService.Models;
using Wq.Extensions.Common;
using Wq.Extensions.Repository;
using Wq.ManagerService;
using Wq.Model;

namespace Wq.Application
{
    public class CaseApplication : BaseApplication
    {
        private readonly AdviserService adviserService;
        private readonly CaseService.CategoryService categoryService;
        private readonly ExampleFeaturesService exampleFeaturesService;
        private readonly ExampleService exampleService;
        private readonly IndustryService industryService;
        private readonly MemberService memberService;
        private readonly ProcessService processService;
        private readonly RedisBaseRepository redisRepository;
        private readonly ManagerService.LogService logService;
        private readonly ActivityService activityService;
        public CaseApplication(AdviserService adviserService,
            CaseService.CategoryService categoryService,
            ExampleFeaturesService exampleFeaturesService,
            ExampleService exampleService,
            IndustryService industryService,
            MemberService memberService,
            ProcessService processService,
            ActivityService activityService,
            RedisBaseRepository redisRepository, 
            ManagerService.LogService logService)
        {
            this.adviserService = adviserService;
            this.categoryService = categoryService;
            this.exampleFeaturesService = exampleFeaturesService;
            this.exampleService = exampleService;
            this.industryService = industryService;
            this.memberService = memberService;
            this.activityService = activityService;
            this.processService = processService;
            this.redisRepository = redisRepository;
            this.logService = logService;
        }
        
        #region 实列
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="info"></param>
        public void Create(ExampleEdit info)
        {
            exampleService.Create(info);
            Log(newData: info);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="info"></param>
        public void Save(ExampleEdit info)
        {
            var old = ExampleeEdit(info.Id);
            exampleService.Save(info);
            redisRepository.Remove(SysCacheKey.ExampleModel(info.Id));
            Log(oldData: old, newData: info, isDelete: true);
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        public void Delete(long id)
        {
            var old = ExampleeEdit(id);
            exampleService.Delete(id);
            redisRepository.Remove(SysCacheKey.ExampleModel(id));
            Log(oldData: old, isDelete: true);
        }

        /// <summary>
        /// 获取编辑实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ExampleEdit ExampleeEdit(long id)
        {
            var info = ExampleDetails(id);
            var model = info.Map<ExampleEdit>();
            model.FeaturesIds = info.Features.Select(p => p.FeaturesId).ToList();
            model.Images = info.Thumbnails.Select(p => p.FilePath).ToList();
            return model;
        }
        /// <summary>
        /// 获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ExampleInfo ExampleDetails(long id) =>
            redisRepository.Get(SysCacheKey.ExampleModel(id), () => { return exampleService.Details(id); }).Result;


        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="oldData"></param>
        /// <param name="newData"></param>
        /// <param name="isDelete"></param>
        public void Log(ExampleEdit oldData = null, ExampleEdit newData = null, bool isDelete = false)
        {
            string msg = string.Empty;
            if (isDelete)
                msg = $"删除实列【{oldData.Name}】";
            else
            {
                if (newData.Id == 0)
                    msg = $"新增实列【{newData.Name}】";
                else
                {
                    msg = $"修改实列【{newData.Name}】";
                    if (newData.Name != oldData.Name)
                        msg += $" 名称由【{newData.Name}】变为【{newData.Name}】";
                }
            }
            logService.Create(LogModule.Example, msg);
        }


        /// <summary>
        /// 修改排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sequence"></param>
        public void ExampleUpdateSequence(long id, long sequence) => exampleService.UpdateSequence(id, sequence);

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="pageModel"></param>
        /// <returns></returns>
        public MessageModel List(PageModel<ExampleQuery> pageModel) => new MessageModel { Data = exampleService.List(pageModel), Count = pageModel.Page.Num };

        /// <summary>
        /// 查询前多少条案例
        /// </summary>
        /// <param name="CategoryId"></param>
        /// <param name="top"></param>
        /// <returns></returns>
        public List<ExampleBaseView> ExampleByCategoryId(long CategoryId, int top) => exampleService.ExampleByCategoryId(CategoryId, top);
        #endregion

        #region 分类
        private void Verify(CategoryInfo model)
        {
            if (string.IsNullOrWhiteSpace(model.Name))
                throw new MyException("分类名称不能为空");
            if (categoryService.Count(p => p.Name == model.Name && p.Id != model.Id) > 0)
                throw new MyException("分类名称已经存在");
        }

        /// <summary>
        ///  添加分类
        /// </summary>
        /// <param name="model"></param>
        public async void Create(CategoryInfo model)
        {
            Verify(model);
            categoryService.Insert(model);
            await redisRepository.Remove(SysCacheKey.ExampleCategories);
        }
        /// <summary>
        /// 修改分类
        /// </summary>
        /// <param name="model"></param>
        public async void Update(CategoryInfo model)
        {
            Verify(model);
            categoryService.Update(model);
            await redisRepository.Remove(SysCacheKey.ExampleCategories);
        }

        /// <summary>
        /// 删除分类
        /// </summary>
        /// <param name="id"></param>
        /// <exception cref="MyException"></exception>
        public async void CategoryDelete(long id)
        {
            if (exampleService.Count(p => p.CategoryId == id) > 0)
                throw new MyException("实列下存在实列，不能删除");
            categoryService.DeleteById(id);
            await redisRepository.Remove(SysCacheKey.ExampleCategories);
        }

        // <summary>
        /// 分类列表
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<CategoryInfo> Categorys()
        {
            return redisRepository.Get(SysCacheKey.ExampleCategories, () =>
            {
                return categoryService.GetList().OrderByDescending(p => p.Sequence).ToList();
            }).Result;
        }

        /// <summary>
        /// 修改排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sequence"></param>
        public void UpdateCategorySequence(long id, long sequence)
        {
            categoryService.UpdateSequence(id, sequence);
            redisRepository.Remove(SysCacheKey.ExampleCategories);
        }
        #endregion

        #region 顾问
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="model"></param>
        public void Verify(AdviserInfo model)
        {
            if (string.IsNullOrWhiteSpace(model.Name))
                throw new MyException("请填写用户名");
            model.Name = model.Name.Trim(); //清除空格
            if (string.IsNullOrWhiteSpace(model.Password) && model.Id == 0)
                throw new MyException("请填写密码");
            model.Password = model.Password.Trim(); //清除空格

            if (adviserService.Count(p => p.Name == model.Name && p.Id != model.Id) > 0)
                throw new MyException("用户名已存在");
            if (adviserService.Count(p => p.Phone == model.Phone && p.Id != model.Id) > 0)
                throw new MyException("手机号已存在");
        }
        /// <summary>
        /// 添加顾问
        /// </summary>
        /// <param name="model"></param>
        public void Create(AdviserInfo model)
        {
            Verify(model);
            model.PasswordSalt = EncryptionHelper.BuildSalt();
            model.Password = EncryptionHelper.GetPasswrodWithTwiceEncode(model.Password, model.PasswordSalt);
            model.CreateDate = DateTime.Now;
            adviserService.Insert(model);
            Log(newData: model);
        }

        /// <summary>
        /// 编辑顾问
        /// </summary>
        /// <param name="model"></param>
        public void Update(AdviserInfo model)
        {
            Verify(model);
            var old = adviserService.GetById(model.Id);
            model.CreateDate = old.CreateDate;
            if (!string.IsNullOrEmpty(model.Password))
            {
                model.PasswordSalt = EncryptionHelper.BuildSalt();
                model.Password = EncryptionHelper.GetPasswrodWithTwiceEncode(model.Password, model.PasswordSalt);
            }
            else
            {
                model.PasswordSalt = old.PasswordSalt;
                model.Password = old.Password;
            }
            adviserService.Update(model);
            Log(old, model , true);
        }

        /// <summary>
        /// 删除顾问
        /// </summary>
        /// <param name="id"></param>
        public void AdviserDelete(long id)
        {
            var old = adviserService.GetById(id);
            adviserService.DeleteById(id);
            Log(oldData: old, isDelete: true);
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="pageModel"></param>
        /// <returns></returns>
        public MessageModel List(PageModel<AdviserQuery> pageModel)
        {
            var exp = Expressionable.Create<AdviserInfo>()
                .AndIF(!string.IsNullOrWhiteSpace(pageModel.Entity.Name), p => p.Name.Contains(pageModel.Entity.Name))
                .AndIF(!string.IsNullOrWhiteSpace(pageModel.Entity.Phone), p => p.Phone.Contains(pageModel.Entity.Phone))
                .ToExpression();
            var list = adviserService.GetPageList(exp, new SqlSugar.PageModel { PageIndex = pageModel.Page.Index, PageSize = pageModel.Page.Size, TotalCount = pageModel.Page.Num }).Map<AdviserView>();
            return new MessageModel { Data = list, Count = pageModel.Page.Num };
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="oldData"></param>
        /// <param name="newData"></param>
        /// <param name="isDelete"></param>
        public void Log(AdviserInfo oldData = null, AdviserInfo newData = null, bool isDelete = false)
        {
            string msg = string.Empty;
            if (isDelete)
                msg = $"删除顾问【{oldData.Name}】";
            else
            {
                if (newData.Id == 0)
                    msg = $"新增顾问【{newData.Name}】";
                else
                {
                    msg = $"修改顾问【{newData.Name}】";
                    if (newData.Name != oldData.Name)
                        msg += $" 名称由【{newData.Name}】变为【{newData.Name}】";
                }
            }
            logService.Create(LogModule.Adviser, msg);
        }

        #endregion

        #region 行业
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="MyException"></exception>
        private void Verify(IndustryInfo model)
        {
            if (string.IsNullOrWhiteSpace(model.Name))
                throw new MyException("行业名称不能为空");
            if (industryService.Count(p => p.Name == model.Name && p.Id != model.Id) > 0)
                throw new MyException("行业名称已经存在");
        }
        /// <summary>
        /// 添加行业
        /// </summary>
        /// <param name="model"></param>
        public async void Create(IndustryInfo model)
        {
            Verify(model);
            industryService.Insert(model);
            await redisRepository.Remove(SysCacheKey.ExampleIndustrys);
        }
        /// <summary>
        /// 编辑行业
        /// </summary>
        /// <param name="model"></param>
        public async void Update(IndustryInfo model)
        {
            Verify(model);
            industryService.Update(model);
            await redisRepository.Remove(SysCacheKey.ExampleIndustrys);
        }
        /// <summary>
        /// 删除行业
        /// </summary>
        /// <param name="id"></param>
        /// <exception cref="MyException"></exception>
        public async void IndustryDelete(long id)
        {
            if (exampleService.Count(p => p.IndustryId == id) > 0)
                throw new MyException("行业下存在实列，不能删除");
            industryService.DeleteById(id);
            await redisRepository.Remove(SysCacheKey.ExampleIndustrys);
        }
        /// <summary>
        /// 行业列表
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<IndustryInfo> Industrys(string name)
        {
            return redisRepository.Get(SysCacheKey.ExampleIndustrys, () =>
            {
                var exp = Expressionable.Create<IndustryInfo>().AndIF(!string.IsNullOrWhiteSpace(name), p => p.Name.Contains(name)).ToExpression();
                return industryService.GetList(exp).OrderByDescending(p => p.Sequence).ToList();
            }).Result;
        }
        /// <summary>
        /// 修改排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sequence"></param>
        public void UpdateIndustrySequence(long id, long sequence)
        {
            industryService.UpdateSequence(id, sequence);
            redisRepository.Remove(SysCacheKey.ExampleIndustrys);
        }
        #endregion

        #region 客户需求
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="MyException"></exception>
        private void Verify(ActivityInfo model)
        {
            if (string.IsNullOrWhiteSpace(model.Name))
                throw new MyException("客户需求名称不能为空");
            if (activityService.Count(p => p.Name == model.Name && p.Id != model.Id) > 0)
                throw new MyException("客户需求名称已经存在");
        }

        /// <summary>
        /// 添加 客户需求
        /// </summary>
        /// <param name="model"></param>
        public async void Create(ActivityInfo model)
        {
            Verify(model);
            activityService.Insert(model);
            await redisRepository.Remove(SysCacheKey.ExampleActivity);
        }
        /// <summary>
        /// 编辑 客户需求
        /// </summary>
        /// <param name="model"></param>
        public async void Update(ActivityInfo model)
        {
            Verify(model);
            activityService.Update(model);
            await redisRepository.Remove(SysCacheKey.ExampleActivity);
        }
        /// <summary>
        /// 删除 客户需求
        /// </summary>
        /// <param name="id"></param>
        /// <exception cref="MyException"></exception>
        public async void IndustryInfoDelete(long id)
        {
            //  if (exampleService.Count(p => p.IndustryId == id) > 0)
            //     throw new MyException("订单下下存在实列，不能删除");
            activityService.DeleteById(id);
            await redisRepository.Remove(SysCacheKey.ExampleActivity);
        }
        /// <summary>
        ///  客户需求列表
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<ActivityInfo> Activitys()
        {
            return redisRepository.Get(SysCacheKey.ExampleActivity, () =>
            {
                return activityService.GetList().OrderByDescending(p => p.Sequence).ToList();
            }).Result;
        }
        /// <summary>
        /// 客户修改排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sequence"></param>
        public void UpdateActivitySequence(long id, long sequence)
        {
            activityService.UpdateSequence(id, sequence);
            redisRepository.Remove(SysCacheKey.ExampleActivity);
        }
        #endregion
    }
}
